#pragma once
#include<iostream>
using namespace std;
#include<stdlib.h>
#include<assert.h>
namespace dj
{
	template<class T>
	class vector
	{
		typedef T* iterator;
		typedef const T* const_iterator;
	public:
		vector()
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_storage(nullptr)
		{

		}
		vector(const vector<T>& v)
		{
			_start = new T[v.capacity()];
			_finish = _start + v.size();
			_end_of_storage = _start + v.capacity();
			int i = 0;
			while (i < v.capacity())
			{
				_start[i] = v._start[i];
				i++;
			}
		}
		bool empty()const
		{
			return size()==0;
		}
		void pop_back()
		{
			assert(size());
			_finish--;
		}
		iterator begin()
		{
			return _start;
		}
		iterator end()
		{
			return _finish;
		}
		const_iterator begin()const
		{
			return _start;
		}
		const_iterator end()const
		{
			return _finish;
		}
		void push_back(const T& val)
		{
			if (size() == capacity())
			{
				size_t newcapacity = size() == 0 ? 4 : 2 * capacity();
				reverse(newcapacity);
			}
			_start[size()] = val;
			_finish++;
		}
		void Display()
		{
			size_t sz = size();
			int i = 0;
			while (i < sz)
			{
				cout << _start[i] << " ";
				i++;
			}
			cout << endl;
		}
		void reverse(size_t n)
		{
			if (n > capacity())
			{
				size_t sz = size();
				size_t	newcapacity = n;
				T* newnode = new T[n];
				/*memcpy(newnode, _start, sz*sizeof(T));*/
				int i = 0;
				while (i < sz)
				{
					newnode[i] = _start[i];
					i++;
				}
				delete[]_start;
				_start = newnode;
				_finish = _start + sz;
				_end_of_storage = _start + n;
			}
		}
		void insert(iterator pos, const T& val)
		{
			int rang = pos - _start;
			if (size() == capacity())
			{

				size_t newcapacity= size()==0?4:2*capacity();
				reverse(newcapacity);

			}
			pos = _start + rang;
			iterator ret = _finish;
			
			while (ret > pos)
			{
				*ret = *(ret - 1);
				ret--;
			}
			*pos = val;
			_finish++;
		}
		void erase(iterator pos)
		{
			assert(!empty());
			iterator begin = pos;
			while (begin < _finish - 1)
			{
				*begin = *(begin + 1);
				begin++;
			}
			_finish--;
		}
		T& front()const
		{
			assert(!empty());
			return *_start;

		}
		const T& back()const
		{
			assert(!empty());
			return _start[size() - 1];
		}
		size_t size()const
		{
			return _finish - _start;
		}
		size_t capacity()const
		{
			return _end_of_storage - _start;
		}
		~vector()
		{
			delete[]_start;
			_start = _finish = _end_of_storage = nullptr;
		}
	private:
		iterator _start;
		iterator _finish;
		iterator _end_of_storage;

	};
}
